package com.groupseven.backend.configuration.shiro;


import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.groupseven.backend.domain.User.User;
import com.groupseven.backend.services.AuthoritiesService;
import com.groupseven.backend.services.UserService;
import com.groupseven.backend.test.DataEncode;
import com.groupseven.backend.util.Jwt.JwtToken;
import com.groupseven.backend.util.Jwt.JwtUtil;
import com.groupseven.backend.util.RedisUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;

/**
 * realm类
 */
public class MyRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;
    @Autowired
    private AuthoritiesService authoritiesService;
    @Autowired
    private DataEncode dataEncode;
    @Autowired
    private RedisUtil redis;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("进入鉴权");
        // 获取当前登录用户
        Subject subject = SecurityUtils.getSubject();
        User user = new User();
        System.out.println(subject.getPrincipal().toString());
        user=(User)subject.getPrincipal();
        System.out.println("鉴权中username："+user.getUsername());
        // 获取 SimpleAuthorizationInfo 对象写入授权规则
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        // 创建一个 set 集合用来保存当前用户的授权信息
        Set<String> stringSet = new HashSet<>();
        //stringSet.add(user.getPerms());
//        stringSet = authoritiesService.getPermissionsByUsername(user);
        stringSet = authoritiesService.getPermissionsByRole(user);
        for (String i : stringSet){
            System.out.println("-------------");
            System.out.println(i);
            System.out.println("-------------");
        }
        info.setStringPermissions(stringSet);
        // 将授权信息写入 SimpleAuthorizationInfo 对象中
        return info;
    }

    /**
     * 认证
     * @param
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) {
        System.out.println("进入认证");
        String token = (String) auth.getCredentials();  //JwtToken中重写了这个方法了
        String username = JwtUtil.getUsername(token);   // 获得username
        System.out.println(token);
        System.out.println("哈哈哈");
        DecodedJWT decodedJWT = JWT.decode(token);
        String Password = decodedJWT.getClaim("password").asString();
        System.out.println(Password);
        //用户不存在（这个在登录时不会进入，只有在token校验时才有可能进入）
        if(username == null) {
            System.out.println("用户不存在");
            throw new UnknownAccountException();
        }
        //根据用户名，查询数据库获取到正确的用户信息
        User user = userService.selectByUsername(username);
        String Username = dataEncode.decodeBae64(username);

        //用户不存在（这个在登录时不会进入，只有在token校验时才有可能进入）
        if(user == null) {
            System.out.println("用户不存在");
            throw new UnknownAccountException();
        }
        //密码错误(这里获取到password，就是3件套处理后的保存到数据库中的凭证，作为密钥)
        if (!Password.equals(userService.selectByUsername(username).getPassword())) {
            System.out.println("密码错误");
            throw new IncorrectCredentialsException();
        }
        //toke过期
        if(redis.hasKey(Username+"在登录")){
            if(redis.get(Username+"在登录").equals("1")){
                if(redis.hasKey(Username+"的token")){
                    redis.del(Username+"的token");
                    redis.set(Username+"的token",token);
                } else {
                    redis.set(Username+"的token",token);
                }
                redis.del(Username+"在登录");
            }
        } else {
            if(redis.hasKey(Username+"的token")){
                if(redis.get(Username+"的token").equals(token)){
                } else {
                    System.out.println("过期了！");
                    throw new ExpiredCredentialsException();
                }
            }
        }
        if(JwtUtil.isExpire(token)){
            System.out.println("token过期");
            throw new ExpiredCredentialsException();
        }

        return new SimpleAuthenticationInfo(user, token, getName());
    }
}
